<template>
  <div
    class="data-statistical custom-el-plus"
    element-loading-background="rgba(0,0,0,0.5)">
    <div class="top-wrapper">
      <div class="chart-box">
        <Title titleName="事件时间分布热力图"></Title>
        <div class="chart-content">
          <CalendarHeatmap
            v-if="!oneDayFlag && props.timeHeatMapData.length"
            :chartData="props.timeHeatMapData"></CalendarHeatmap>
          <TimeHeatmap
            v-if="oneDayFlag && props.timeHeatMapData.length"
            :chartData="props.timeHeatMapData"></TimeHeatmap>
        </div>
      </div>
      <div class="rank-list">
        <Title titleName="事件预警点位排行"></Title>
        <div
          class="rank-list-content"
          v-if="props.rankList?.length">
          <div
            class="list-item"
            v-for="(item, index) in props.rankList"
            :key="index">
            <div
              class="item-index"
              :style="{ background: index > 2 ? '#4464BD' : index === 0 ? '#e04f3f' : index === 1 ? '#D67609' : '#34AD54' }">
              {{ index + 1 }}
            </div>
            <div class="item-info">
              <div class="item-text">
                <div>{{ item.crossName }}</div>
                <div>{{ item.count }}次</div>
              </div>
              <div class="item-bar">
                <div
                  class="bar-bg"
                  :style="{ width: (item.count / ranListMaxCount) * 100 + '%' }"></div>
              </div>
            </div>
          </div>
        </div>
        <div
          class="rank-img-content"
          v-else>
          <img
            :src="rankDefaultBg"
            alt="" />
          <div>暂无排行</div>
        </div>
      </div>
    </div>
    <div class="map-wrapper">
      <Title titleName="事件空间分布热力图"></Title>
      <div
        class="map-container"
        id="heatMap"></div>
    </div>
    <div class="table-wrapper">
      <Title titleName="事件分析对比"></Title>
      <div class="table-content">
        <div
          class="main-table"
          v-if="props.eventComparisonList.length > 0">
          <el-table
            :header-cell-class-name="handleTableHeaderClassName"
            :cell-class-name="handleTableCellClassName"
            :data="(props, eventComparisonList)"
            style="width: 100%">
            <el-table-column
              label="名称"
              prop="alarmName"
              width="250"></el-table-column>
            <el-table-column
              label="占比"
              prop="rate"
              width="250"></el-table-column>
            <el-table-column
              label="发生点位数"
              prop="pointCount"
              width="250"></el-table-column>
            <el-table-column
              label="发生频率"
              prop="frequency"
              width="250">
              <template #default="{ row }">
                <div>{{ row.frequency }}&nbsp;&nbsp;次/每小时</div>
              </template></el-table-column
            >
            <el-table-column
              className="bar-container"
              label=""
              prop="">
              <template #default="{ row }">
                <div class="bar-wrapper">
                  <div
                    class="table-bar-bg"
                    :style="{ width: (row.count / eventListMaxCount) * 100 + '%' }">
                    &nbsp;
                  </div>
                  <div class="bar-text">{{ row.count }}</div>
                </div>
              </template></el-table-column
            >
          </el-table>
        </div>
        <div
          class="main-table"
          v-else>
          <el-table
            :data="[]"
            style="width: 100%">
            <el-table-column
              label="名称"
              prop=""
              width=""></el-table-column>
            <el-table-column
              label="占比"
              prop=""
              width=""></el-table-column>
            <el-table-column
              label="发生点位数"
              prop=""
              width=""></el-table-column>
            <el-table-column
              label="发生频率"
              prop=""
              width=""></el-table-column>
          </el-table>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
  import { computed, getCurrentInstance, onMounted, watch, ref, nextTick } from 'vue'
  import Title from '@/components/title/index.vue'
  import CalendarHeatmap from './calendarHeatmap.vue'
  import TimeHeatmap from './timerHeatmap.vue'
  import MapInit from '@/utils/mineMap/MapInit'
  import rankDefaultBg from '@/assets/img/page/rankDefaultBg.png'

  /* =============数据============== */
  const { proxy } = getCurrentInstance()
  const props = defineProps({
    rankList: {
      type: Array,
      default: []
    },
    eventComparisonList: {
      type: Array,
      default: []
    },
    spaceHeatMapData: {
      type: Array,
      default: []
    },
    timeHeatMapData: {
      type: Object,
      default: {}
    }
  })
  const ranListMaxCount = computed(() => {
    let arr = props.rankList.map(item => +item.count)
    return Math.max(...arr) || 1
  })
  const eventListMaxCount = computed(() => {
    let arr = props.eventComparisonList.map(item => +item.count)
    return Math.max(...arr) || 1
  })
  const mapObject = {
    darkMapObj: null,
    mapCenter: []
  }
  const spaceHeatMapGeoJson = ref()
  const maxSpaceHeatMapValue = ref(0)
  const oneDayFlag = computed(() => {
    if (props.timeHeatMapData.length) {
      if (props.timeHeatMapData[0].dayOfWeek !== undefined) {
        return false
      } else {
        return true
      }
    } else {
      return false
    }
  })
  /* =============方法============== */

  const initMap = () => {
    mapObject.darkMapObj = new MapInit('heatMap', {
      center: [114.88923193324109, 40.76546125305629]
    })
    mapObject.darkMapObj.on('load', () => {
      drawHeatMap()
    })
  }
  const drawHeatMap = () => {
    getMaxSpaceHeatMapValue(props.spaceHeatMapData)
    handleSpaceHeatMapData(props.spaceHeatMapData)
    addHeatmapSouce()
    addHeatmapLayer()
  }
  const handleResRegionData = nodes => {
    return nodes.map(node => {
      const newNode = {
        ...node,
        value: node.name,
        label: node.name
      }
      if (node.children) {
        newNode.children = handleResRegionData(node.children)
      }

      return newNode
    })
  }
  const handleTableHeaderClassName = ({ columnIndex }) => {
    if (columnIndex === 4) {
      return 'display-header-none'
    }
  }
  const handleTableCellClassName = ({ columnIndex }) => {
    if (columnIndex === 4) {
      return 'special-cell'
    }
  }
  const getCircleRadius = data => {
    let maxRadius = 50
    let minRadius = 10
    let k = (maxRadius - minRadius) / maxSpaceHeatMapValue.value
    return maxRadius - k * (maxSpaceHeatMapValue.value - data)
  }
  const getCircleColor = data => {
    if (maxSpaceHeatMapValue.value === 0) {
      return {
        bgColor: '#34AD54',
        borderColor: 'rgba(52, 173, 84, 0.40)'
      }
    } else {
      if (data >= maxSpaceHeatMapValue.value * 0.7) {
        return {
          bgColor: '#E04F3F',
          borderColor: 'rgba(224, 79, 63, 0.40)'
        }
      } else if (data >= maxSpaceHeatMapValue.value * 0.3 && data < maxSpaceHeatMapValue.value * 0.7) {
        return {
          bgColor: '#D69009',
          borderColor: 'rgba(214, 144, 9, 0.40)'
        }
      } else {
        return {
          bgColor: '#34AD54',
          borderColor: 'rgba(52, 173, 84, 0.40)'
        }
      }
    }
  }
  const handleSpaceHeatMapData = data => {
    if (data?.length) {
      spaceHeatMapGeoJson.value = null
      let geoData = {
        type: 'FeatureCollection',
        features: []
      }
      geoData.features = data.map(item => {
        let colorObj = getCircleColor(+item.count)
        let radius = getCircleRadius(+item.count)
        return {
          type: 'Feature',
          properties: {
            count: +item.count,
            radius,
            color: colorObj.bgColor,
            borderColor: colorObj.borderColor,
            borderWidth: radius / 8 < 4 ? 4 : radius / 8
          },
          geometry: {
            type: 'Point',
            coordinates: [+item.longitude, +item.latitude]
          }
        }
      })
      spaceHeatMapGeoJson.value = geoData
    } else {
      spaceHeatMapGeoJson.value = {
        type: 'FeatureCollection',
        features: []
      }
    }
  }
  const getMaxSpaceHeatMapValue = data => {
    if (data?.length) {
      let valueArr = data.map(item => +item.count)
      valueArr.length > 0 ? (maxSpaceHeatMapValue.value = Math.max(...valueArr)) : (maxSpaceHeatMapValue.value = 0)
    } else {
      maxSpaceHeatMapValue.value = 0
    }
  }
  const addHeatmapSouce = () => {
    let source = mapObject.darkMapObj.getSource('heatmap-source')
    if (source) {
      source.setData(spaceHeatMapGeoJson.value)
    } else {
      mapObject.darkMapObj.addSource('heatmap-source', {
        type: 'geojson',
        data: spaceHeatMapGeoJson.value
      })
    }
  }
  const addHeatmapLayer = () => {
    if (mapObject.darkMapObj.getLayer('heatmap-layer')) {
      mapObject.darkMapObj.removeLayer('heatmap-layer')
    }
    mapObject.darkMapObj.addLayer({
      id: 'heatmap-layer',
      type: 'circle',
      source: 'heatmap-source',
      paint: {
        'circle-radius': ['get', 'radius'],
        'circle-color': ['get', 'color'],
        'circle-stroke-color': ['get', 'borderColor'],
        'circle-stroke-width': ['get', 'borderWidth']
      }
    })
  }
  watch(
    () => props.spaceHeatMapData,
    (newVal, oldVal) => {
      try {
        nextTick(() => {
          getMaxSpaceHeatMapValue(newVal)
          handleSpaceHeatMapData(newVal)
          addHeatmapSouce()
          addHeatmapLayer()
        })
      } catch (error) {
        console.log(error)
      }
    },
    { deep: true, immediate: false }
  )
  onMounted(() => {
    initMap()
  })
</script>

<style scoped lang="scss">
  .data-statistical {
    padding: 0 pxTvw(24) pxTvh(24) pxTvw(24);
    margin-top: pxTvh(50);
    background: #0d172f;
    color: #a5adba;
    @include computed_font(14);
    overflow-y: scroll;
    & > .top-wrapper {
      display: flex;
      justify-content: space-between;
      box-sizing: border-box;
      height: pxTvh(500);
      margin: pxTvh(0) 0 pxTvh(16) 0;
      padding-top: pxTvh(24);
      & > .chart-box {
        flex: 3;
        & > .chart-content {
          margin-right: pxTvw(32);
        }
      }
      & > .rank-list {
        flex: 2;
        display: flex;
        flex-direction: column;

        & > .rank-list-content {
          flex: 1;
          overflow-y: scroll;
          & > .list-item {
            display: flex;
            align-items: center;
            justify-content: space-between;
            height: pxTvh(35);
            margin-bottom: pxTvh(24);
            & > .item-index {
              width: pxTvw(24);
              height: pxTvw(24);
              background: #4464bd;
              border-radius: pxTvw(2);
              margin-right: pxTvw(16);
              display: flex;
              align-items: center;
              justify-content: center;
              color: #fff;
            }
            & > .item-info {
              height: 100%;
              display: flex;
              flex-direction: column;
              flex: 1;
              & > .item-text {
                display: flex;
                justify-content: space-between;
                align-items: center;
                margin-bottom: pxTvh(4);
              }
              & > .item-bar {
                width: 100%;
                height: pxTvh(8);
                background: #32498a;
                position: relative;
                & > .bar-bg {
                  height: 100%;
                  background: linear-gradient(90deg, #2275f0 0%, #70eafc 63%);
                  position: absolute;
                  left: 0;
                  top: 0;
                  bottom: 0;
                }
              }
            }
          }
          & > .list-item:last-child {
            margin-bottom: 0;
          }
        }
        & > .rank-img-content {
          display: flex;
          align-items: center;
          justify-content: center;
          height: 100%;
          flex-direction: column;
          color: rgba(98, 120, 164, 1);
        }
      }
    }
    & > .map-wrapper {
      display: flex;
      flex-direction: column;
      height: pxTvh(1000);
      margin-bottom: pxTvh(16);
      & > .map-container {
        @include wh100();
      }
    }
    & > .table-wrapper {
      display: flex;
      flex-direction: column;
      box-sizing: border-box;
      overflow: hidden;
      & > .table-content {
        display: flex;
        justify-content: space-between;
        height: calc(100% - #{pxTvh(44)});
        overflow-y: scroll;

        & > .main-table {
          flex: 1;
          :deep .el-table {
            .display-header-none {
              background-color: #0d172f;
              border: none;
            }
            .special-cell {
              background-color: #0d172f;
              border: none;
            }
            .el-table__inner-wrapper:before {
              height: 0;
            }
          }
          .bar-container {
            .bar-wrapper {
              width: 100%;
              height: 100%;
              display: flex;
              color: #fff;
              .table-bar-bg {
                height: 100%;
                background-color: #165dff;
                margin-right: pxTvw(8);
              }
            }
          }
        }
      }
    }
  }
</style>
